#ifndef xpack_macro_xstruct_op
#define xpack_macro_xstruct_op
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::macro_xstruct_op
#include"macro/xforward.hpp"
#include"macro/private/xstruct.concept.hpp"
#pragma pop_macro("xuser")

///////////// 支持运算符重载转发
// 使用 decltype(auto) 配合 return (xxx) 的方式，同时支持返回引用和非引用类型
template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_eq<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator==(__prop_t const & left, __arg_t && right){
    return (left() == xforward(right));
}

template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_ne<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator!=(__prop_t const & left, __arg_t && right){
    return (left() != xforward(right));
}

template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_gt<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator>(__prop_t const & left, __arg_t && right){ 
    return (left() > xforward(right));
}

template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_ge<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator>=(__prop_t const & left, __arg_t && right){
    return (left() >= xforward(right));
}

template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_lt<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator<(__prop_t const & left, __arg_t && right){ 
    return (left() < xforward(right));
}

template<__is_prop __prop_t, class __arg_t>
requires(__is_prop<__arg_t> == false and __can_cmp_le<typename __prop_t::__get_t, __arg_t>)
inline decltype(auto) operator<=(__prop_t const & left, __arg_t && right){
    return (left() <= xforward(right));
}




template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_eq<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator==(__prop_left_t const & left, __prop_right_t const & right){
    return (left() == right());
}

template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_ne<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator!=(__prop_left_t const & left, __prop_right_t const & right){
    return (left() != right());
}

template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_gt<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator>(__prop_left_t const & left, __prop_right_t const & right){ 
    return (left() > right());
}

template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_ge<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator>=(__prop_left_t const & left, __prop_right_t const & right){
    return (left() >= right());
}

template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_lt<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator<(__prop_left_t const & left, __prop_right_t const & right){ 
    return (left() < right());
}

template<__is_prop __prop_left_t, __is_prop __prop_right_t>
requires(__can_cmp_le<typename __prop_left_t::__get_t, typename __prop_right_t::__get_t>)
inline decltype(auto) operator<=(__prop_left_t const & left, __prop_right_t const & right){
    return (left() <= right());
}




template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_eq<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator==(__arg_t && left, __prop_t const & right){
    return (xforward(left) == right());
}

template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_ne<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator!=(__arg_t && left, __prop_t const & right){
    return (xforward(left) != right());
}

template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_gt<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator>(__arg_t && left, __prop_t const & right){ 
    return (xforward(left) > right());
}

template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_ge<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator>=(__arg_t && left, __prop_t const & right){
    return (xforward(left) >= right());
}

template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_lt<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator<(__arg_t && left, __prop_t const & right){ 
    return (xforward(left) < right());
}

template<class __arg_t, __is_prop __prop_t>
requires(__is_prop<__arg_t> == false and __can_cmp_le<__arg_t, typename __prop_t::__get_t>)
inline decltype(auto) operator<=(__arg_t && left, __prop_t const & right){
    return (xforward(left) <= right());
}

#endif
